<?php

namespace app\api\service\weixin;

use app\admin\model\Groupdetail;
use app\admin\model\Groupproduct;
use app\admin\model\Member;
use app\admin\model\Orderitem;
use app\api\controller\Integralproduct;
use app\api\service\Detailed;
use app\common\DictConstant;
use app\common\service\TemplateMessage;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Db;
use think\Exception;
use think\Log;

class OrderPay extends BasePay
{
    private $orderID;

    function __construct($orderID)
    {
        if(!$orderID){
            throw new Exception('订单号不能为空');
        }
        $this->orderID = $orderID;
    }

    /**
     * 微信支付
     * @return \think\response\Json
     * @throws TokenException
     */
    public function pay(){
        //订单号可能根本就不存在
        //订单号确实是存在的，但是，订单号和当前用户是不匹配的
        //订单有可能已经被支付过
        //发起支付之前再进行库存量检测
        try{
            $this->checkOrderValid();
        }catch (Exception $ex){
            return show(config('status.ERROR_STATUS'),'订单状态异常',[]);
        }
        $order = \app\admin\model\Order::get($this->orderID);
        $member = \app\admin\model\Member::get($order->member_id);
        $openid = $member->open_id;
        if(!$openid){
            throw new TokenException();
        }
        $Orderitem = Orderitem::where('order_id',$order->id)->find();
        $productName = $Orderitem->product_name;
        $pay_back_url = config('wx.pay_back_url');
        return show(config('status.SUCCESS_STATUS'),'ok',$this->run($order['total'],$productName,$openid,$this->orderID,$pay_back_url));
    }

    /**
     * 存储预支付交易会话标识（重写父类方法）
     * @param $wxOrder
     */
    protected function recordPreOrder($wxOrder){
        \app\admin\model\Order::where('id','=',$this->orderID)->update(['prepay_id'=>$wxOrder['prepay_id']]);
    }


    //余额支付
    public function balancepay($formId){
        try{
            $this->checkOrderValid();
        }catch (Exception $ex){
            return [
                'Balance' => DictConstant::BALANCE_TRUE,
                'isPay' => false
            ];
        }
        $order = \app\common\model\Order::get($this->orderID);
        return $this->goBalancePay($order['total'],$formId,$order['member_id']);
    }

    private function goBalancePay($orderPrice,$formId,$memberId){
        //获取用户余额
        //判断订单金额是否小于等于用户余额
        $PayStatus = [
            'Balance' => DictConstant::BALANCE_TRUE,
            'isPay' => true
        ];
        $user = Member::get($memberId);
        if($user->balance < $orderPrice){
            $PayStatus['Balance'] = DictConstant::BALANCE_FALSE;
            $PayStatus['isPay'] = false;
            return $PayStatus;
        }
        Db::startTrans();
        try
        {
            $order = \app\common\model\Order::where('id','=',$this->orderID)->lock(true)->find();
            if($order->link_type == 1){
                if($order->status == 1){
                    //减余额
                    Member::where('id','=',$memberId)->setDec('balance',$orderPrice);
                    //改变用户首单立减状态
                    if($order->first_order_reduce >0){
                        Member::where('id','=',$memberId)->update(['isfirst_order_reduce'=>1]);
                    }
                    //更新订单状态
                    $this->updateOrderStatus($order->id,$order->link_type);
                    //更新订单占用库存
                    $this->reduceStock($order->id);
                    //更新销量
                    OrderNotify::updatesalesvolume($order->id);

                }
            }elseif ($order->link_type == 2){
                //减余额
                Member::where('id','=',$memberId)->setDec('balance',$orderPrice);
                //更新订单状态
                $this->updateOrderStatus($order->id,$order->link_type);
                //更新订单占用库存
                $this->reduceStock($order->id);
                //改变用户拼团状态
                $this->updateUserGroupStatus($order->id);
            }

            Db::commit();
            //插入余额消费明细
            Detailed::insertDetailed($order);
            //消费送积分
            Integralproduct::consumptiongiveintegral($memberId,$order->total,$this->orderID,2);
            return $PayStatus;
        }
        catch (Exception $ex){
            Db::rollback();
            Log::record($ex);
            $PayStatus['isPay'] = false;
            throw $ex;
            return $PayStatus;
        }
    }

    private function updateOrderStatus($orderID,$linkType){
        $paytime = date('Y-m-d H:i:s',time());
        if($linkType == 1){
            $status = DictConstant::OrderPendingDelivery;
        }else{
            $status = DictConstant::Order_GroupIng;
        }
        \app\common\model\Order::where('id','=',$this->orderID)->update(['status'=>$status,'pay_method'=>3,'pay_date'=>$paytime]);
        Orderitem::where('order_id',$orderID)->update(['old_status'=>$status]);

    }

    private function reduceStock($orderId){
        $Orderitem = Orderitem::where('order_id',$orderId)->field('product_id,count')->select();
        foreach ($Orderitem as $v){
            db('stock')->where('product_id',$v['product_id'])->setDec('order_stock',$v['count']);
        }
    }

    private function updateUserGroupStatus($orderID){
        $Groupdetail = Groupdetail::where('order_id',$orderID)->find();  //groupproduct
        $Groupproduct = Groupproduct::get($Groupdetail->group_id);
        $chentuannum = $Groupproduct->group_succ_count;
        $oktime = $Groupproduct->group_succ_time;
        if($Groupdetail->member_id == $Groupdetail->originator){
            $endDate = time()+$oktime;
        }else{
            $tuanzhang = Groupdetail::get($Groupdetail->unigroup_id);
            $endDate = $tuanzhang->end_date;
        }
        $goups = Groupdetail::where('unigroup_id',$Groupdetail->unigroup_id)->lock(true)->count();
        if($chentuannum > $goups){
            $Groupdetail->end_date = $endDate;
            $Groupdetail->status = 1;
            $Groupdetail->is_pay = 1;
            $Groupdetail->save();
            //拼团进度通知（模板消息）
            TemplateMessage::GroupSpeedOfProgress($orderID,$chentuannum,$goups,$endDate);
        }elseif ($chentuannum == $goups){
            $allgroups = Groupdetail::where('unigroup_id',$Groupdetail->unigroup_id)->select();
            $list = [];
            foreach ($allgroups as $v){
                array_push($list,['id'=>$v['id'],'status'=>2,'is_pay'=>1,'end_date'=>$endDate]);
            }
            (new Groupdetail())->saveAll($list);
            //把订单里所有该团的状态改为待发货
            $this->updateGroupOrderStatus($Groupdetail->unigroup_id);
            //拼团成功通知
            TemplateMessage::GroupSuccess($orderID,$chentuannum);
        }else{
            //todo
        }
    }

    private function updateGroupOrderStatus($unigroupId){
        $Groupdetail = Groupdetail::where('unigroup_id',$unigroupId)->select();
        $listorder = [];
        foreach ($Groupdetail as $v){
            $status = DictConstant::OrderPendingDelivery;
            array_push($listorder,['id'=>$v['order_id'],'status'=>$status]);
        }
        $order = new \app\common\model\Order();
        $order->saveAll($listorder);
        $Orderitem = new Orderitem();
        $list = [];
        foreach ($Groupdetail as $value){
            $status = DictConstant::OrderPendingDelivery;
            array_push($list,$value['order_id']);
        }
        $Orderitem->where('order_id','in',$list)->update(['old_status'=>$status]);
    }

    //对订单号进行检测
    private function checkOrderValid(){
        $order = \app\common\model\Order::where('id','=',$this->orderID)->find();
        if(!$order){
            throw new OrderException();
        }
//        if(!Token::isValidOperate($order->member_id)){
//            throw new TokenException([
//                'msg' => '订单与用户不匹配',
//                'errorCode' => 10003
//            ]);
//        }
        if($order->status != DictConstant::OrderPendingPayment){
            throw new OrderException([
                'msg' => '该订单已经支付过了',
                'errorCode' => 80003,
                'code' => 400
            ]);
        }
        return true;

    }
}